vivado RAM使用 | 您所在的位置:网站首页 › vivado 使用bd速度 › vivado RAM使用 |
1.双口RAM概述
双口RAM(dual port RAM)在异构系统中应用广泛,通过双口RAM,不同硬件架构的芯片可以实现数据的交互,从而实现通信。例如,一般情况下,ARM与DSP之间的通信,可以利用双口RAM实现,ARM通过EBI总线连接到双口RAM的A口,DSP通过EMIF总线(也可以是uPP总线,取决于速度需求)连接到双口RAM的B口,两者对同一块存储区域进行操作,即可实现两者的数据交互。 但是,因为双口RAM的A口和B口都可以对相同的内存地址进行操作,这就引出了一个问题——假如通信双方在两个端口对同一地址同时读写,就会引发冲突。要解决这个问题,办法有二。一是通信双方在时序上保证不会同时读写同一地址,将ARM和DSP可写地址范围进行分区,无论任何一方写完数据后都通过IO发送中断通知对方,对方进行数据读取(乒乓RAM操作),这样是比较可靠的;另外一个办法就是在fpga里设置写busy信号,实现两端写同步[]。在FPGA中,构建双口RAM可以通过两种方法,一种是利用distributed RAM构建,另一种是利用Block RAM构建,关于两者的具体区别,可以参考这两篇文章[][]。简而言之,Block RAM是是使用FPGA中的整块双口RAM资源,而distributed RAM则是用FPGA中的逻辑资源拼凑形成的。一般的原则是,较大的存储应用,建议用bram;零星的小ram,一般就用dram。 在Vivado中,RAM IP核在Memories & Strorage Elements\RAM & ROMs和RAM & ROMs & BRAM文件夹下,如图所示,下面简要介绍一下Vivado的双口RAM IP核。 (图1.1) 2.Vivado 双口RAM IP核
2.1 Block Memory Generator概述
点击图1.1的Block Memory Generator项,利用BRAM来构建双口RAM。Block Memory Generator窗口如图2.1所示。 图中,第1部分,在IP symbol选项卡,点击"+"号可以展开端口具体信号,如图2.2所示。第2部分,Component Name可以设置IP核的名字。第3部分,Basic选项卡,在Memory Type下拉列表中,可以设置内存的类型,如图2.3所示。Block Memory Gnerator一共可以产生5种不同类型的内存空间,其中block RAM有三种:单口RAM、简化双口RAM和真双口RAM[]。单口RAM只有一个端口(A端口),可以对A端口进行读写。简化双口RAM有两个端口(A和B端口),但是A端口只能进行写入操作,不能进行读出操作,而B端口则只能进行读出操作,不能进行写入操作。真双口RAM有两个端口(A和B端口),A和B端口都能进行读写操作[]。 (图2.1) (图2.2) (图2.3) 2.2 真双口RAM的设置
2.2.1 Basic设置
在Basic选项卡的Memory type选项中选择真双口RAM,IP Symbol如图2.4所示。ECC Options为默认设置,Write Enable中也选择默认设置,不使能字节写,Algorithm Options选择默认设置。 (图2.4) 2.2.2 Port设置
点击Port A Options选项卡,对A端口进行设置, 设置Write Width为16(即RAM单元为16位),Write Width为1024(即内存深度为1024,该端口可读写的RAM单元有1024个),Operating Mode(操作模式)一共有三种:Write First,Read First,No Change。在Write First模式中,在一个时钟周期里,写入内存单元的数据被同步输出到输出数据总线上;在Read First模式中,在一个时钟周期里,写入到内存单元的数据是当前输入数据总线上的数据,而输出到输出数据总线上的数据则是上一个时钟周期存储在内存单元中的数据。细节可参考PG058的49到50页4。Enable Port Type设置为Always Enabled,一直使能端口A。其它设置使用默认设置。如图2.5所示。 (图2.5) 端口B设置为与A一致。在Other Options选项卡中,保留默认设置。Load Init File设置是否用Coe文件对内存区域初始化,这个在初始化ROM的时候会用到,这里不勾选,保持默认。最后,在Summary选项卡会显示消耗的资源。 3.双口RAM例程
例程1,该例程是Altera官方例程[],采用寄存器构建双口RAM,代码如下: moduletrue_dpram_sclk ( input [7:0] data_a, data_b, input [5:0] addr_a, addr_b, input we_a, we_b, clk, outputreg [7:0] q_a, q_b ); // Declare the RAM variable reg [7:0] ram[63:0];
// Port A always @ (posedge clk) begin if (we_a) begin ram[addr_a] |
CopyRight 2018-2019 实验室设备网 版权所有 |